using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;

namespace UFrame
{
    public enum SkillTestEditorEventEnum
    {
        SelectPlayer,
        SelectAnimationClip,
        RefreshBones,
        EffectChange,
    }

    public class SelectPlayerEventData
    {
        public GameObject go;
        public AnimatorController mAnimatorcontroller;
    }

    public class SelectAnimationClipEventData
    {
        public AnimationClip mClip;
    }

    public class RefreshData
    {
    }

    public class EffectChange
    {
    }


    //其他信息


    public enum CameraShakeType
    {
        CameraShake,
        CameraZoomIn,
        CameraZoomOut,
        CameraZoomRecover,
    }

    [Serializable]
    public class CameraShakeInfo : ICloneable
    {
        public int shakeType;

        public float delayTime = 0.2f;

        // 抖动参数
        public float shakeIntensity = 5f; // 抖动强度    
        public float shakeDuration = 0.2f; // 抖动持续时间    

        public int shakeFps = 22; // 抖动帧数

        // 缩放参数    
        public float zoomIntensity = 2.5f;
        public float zoomRandomRate = 1f;
        public float zoomDuration = 0.25f;
        public float autoRecoverDelay = 1f;


        public object Clone()
        {
            CameraShakeInfo info = new CameraShakeInfo();

            info.shakeType = shakeType;
            info.delayTime = delayTime;
            info.shakeIntensity = shakeIntensity;
            info.shakeDuration = shakeDuration;
            info.shakeFps = shakeFps;
            info.zoomIntensity = zoomIntensity;
            info.zoomRandomRate = zoomRandomRate;
            info.zoomDuration = zoomDuration;
            info.autoRecoverDelay = autoRecoverDelay;

            return info;
        }
    }

    public struct SkillEffectAdditive
    {
        public float preSkillTime;
        public float strikeRange;
        public float moveDist;
        public float castDist;
    }

    [Serializable]
    public class SkillEffectInfo : ICloneable
    {
        // 重要！！！ 只有主角会使用到，其他角色产生位移或延迟的结果会直接同步过来
        public SkillEffectAdditive additive;

        public string name = string.Empty;
        public int skillAnimationID = 0;
        public bool canMove = false;
        public float skillMoveDis = 0f;
        public float skillAnimationLength = 0f;
        public float skillComboTime = 0f;
        public bool targetMove = true;
        public AnimationCurve curve = null;
        public List<SkillEffectData> castEffectList = new List<SkillEffectData>();
        public List<float> hitTimes = new List<float>();
        public List<int> hitDeadEffectType = new List<int>();
        public SkillEffectData hitEffect;
        public SkillEffectData keepEffect;
        public List<SkillEffectData> preSkillEffectList = new List<SkillEffectData>();

        public List<CameraShakeInfo> cameraShakeInfoList = new List<CameraShakeInfo>();

        // 有关逻辑
        public int hitBackType; // 击退类型 1 = 怪物 2 = 怪物和玩家
        public float hitBackTime; // 击退时长
        public float hitBackDis; // 击退距离
        public float penaltyTime; // 判定延迟

        public float findTargetDist;
        public int playerSkillType; // 技能类型 1 = 可指定范围 2 = 不可指定范围 3 = 自身BUFF 4 = 目标型    
        public int attackRangeType; // 0 = 扇形， 1 = 矩形， 2 = 圆形
        public float attackRange;
        public float attackCastDist;
        public int attackTargetType; // 目标类型 1 = 只能敌对， 2 = 友军， 3 = 自身或友军
        public int preSkillIndex; // 前摇动作
        public string preSkillName; // 前摇动作
        public float preSkillTime; // 前摇时长
        public bool isImpect; // 限目标型技能，是否扩散    
        public float impactRange;
        public bool isMonsterDontRotate = false; // 释放该技能时怪物不旋转

        public object Clone()
        {
            SkillEffectInfo info = new SkillEffectInfo();

            info.skillAnimationID = skillAnimationID;
            info.canMove = canMove;
            info.skillMoveDis = skillMoveDis;
            info.skillAnimationLength = skillAnimationLength;
            info.skillComboTime = skillComboTime;
            info.targetMove = targetMove;
            info.curve = new AnimationCurve(curve.keys);
            info.castEffectList = new List<SkillEffectData>();
            foreach (var item in castEffectList)
            {
                info.castEffectList.Add(item.Clone() as SkillEffectData);
            }

            info.hitTimes = new List<float>();
            foreach (var item in hitTimes)
            {
                info.hitTimes.Add(item);
            }

            info.hitDeadEffectType = new List<int>();
            foreach (var item in hitDeadEffectType)
            {
                info.hitDeadEffectType.Add(item);
            }

            info.hitEffect = hitEffect.Clone() as SkillEffectData;
            info.keepEffect = keepEffect.Clone() as SkillEffectData;

            info.preSkillEffectList = new List<SkillEffectData>();
            foreach (var item in preSkillEffectList)
            {
                info.preSkillEffectList.Add(item.Clone() as SkillEffectData);
            }

            info.cameraShakeInfoList = new List<CameraShakeInfo>();
            foreach (var item in cameraShakeInfoList)
            {
                info.cameraShakeInfoList.Add(item.Clone() as CameraShakeInfo);
            }

            info.hitBackType = hitBackType;
            info.hitBackTime = hitBackTime;
            info.hitBackDis = hitBackDis;
            info.playerSkillType = playerSkillType;
            info.attackRangeType = attackRangeType;
            info.attackRange = attackRange;
            info.attackCastDist = attackCastDist;
            info.attackTargetType = attackTargetType;
            info.preSkillIndex = preSkillIndex;
            info.preSkillName = preSkillName;
            info.preSkillTime = preSkillTime;
            info.isImpect = isImpect;

            return info;
        }
    }

    [Serializable]
    public class SkillEffectData : ICloneable
    {
        public SkillEffectType effectType = SkillEffectType.Cast;

        public string effectName = string.Empty;

        // 骨骼点
        public string boneName = string.Empty;

        // 持续时长
        public float effectTimeLength = 0f;

        // 施放延迟
        public float castTime = 0f;

        // 是否绑定
        public bool isBind = false;

        // 不放在父节点下
        public bool isPosition = false;

        // 速度
        public float speed = 0f;

        // 0 = 固定型， 1 = 追踪型
        public int type = 0;

        // 音效
        public string sfxName;

        // 偏移位置
        public Vector3 offer = Vector3.zero;

        // 偏移角度
        public Quaternion rotation = Quaternion.identity;

        // 插值位置
        public AnimationCurve curveCloseto;

        // 动态偏移
        public float motionOffsetX;
        public float motionOffsetY;
        public float motionDist;
        public AnimationCurve curveMotionOffsetX;
        public AnimationCurve curveMotionOffsetY;
        public bool isFollowPlayer; // 是否是追踪玩家的追踪型特效        

        public object Clone()
        {
            SkillEffectData data = new SkillEffectData();
            data.effectType = effectType;
            data.effectName = effectName;
            data.boneName = boneName;
            data.effectTimeLength = effectTimeLength;
            data.castTime = castTime;
            data.isBind = isPosition;
            data.speed = speed;
            data.type = type;
            data.sfxName = sfxName;
            data.offer = offer;
            data.rotation = rotation;
            data.curveCloseto = new AnimationCurve(curveCloseto.keys);
            data.motionOffsetX = motionOffsetX;
            data.motionOffsetY = motionOffsetY;
            data.curveMotionOffsetX = new AnimationCurve(curveMotionOffsetX.keys);
            data.curveMotionOffsetY = new AnimationCurve(curveMotionOffsetY.keys);
            data.motionDist = motionDist;
            data.isFollowPlayer = isFollowPlayer;

            return data;
        }

#if UNITY_EDITOR
        public GameObject EditorGetObject()
        {
            if (!string.IsNullOrEmpty(effectName))
            {
                string[] deps = AssetDatabase.GetAssetPathsFromAssetBundle("effect");
                string keyName = effectName + ".prefab";
                foreach (var d in deps)
                {
                    if (d.Contains(keyName))
                    {
                        return AssetDatabase.LoadAssetAtPath(d, typeof(GameObject)) as GameObject;
                    }
                }
            }

            return null;
        }
#endif
    }

    [Serializable]
    public enum SkillEffectType
    {
        Cast,
        Hit,
        Keep,
        PreSkill,
    }


    public class LongTimeCounter
    {
        long startTime = 0;
        public LongTimeCounter()
        {
            startTime = DateTime.Now.Ticks;
        }

        public float GetPassTime()
        {
            float f = (DateTime.Now.Ticks - startTime) * 0.0000001f;
            return f;
        }

        public long GetPassLongTime()
        {
            long f = (DateTime.Now.Ticks - startTime);
            return f;
        }

        public void ResetCounter()
        {
            startTime = DateTime.Now.Ticks;
        }
    }

    public enum EPlayType
    {
        Normal,
        Bind,
        BindPosition,
        Track,
        Motion,
    }

}